package com.lsyw.intergrate.common;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import org.springframework.lang.Nullable;

import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符工具
 *
 * @author alicas
 */
public class StringUtil {
    /**
     * 下划线
     */
    private static final char SEPARATOR = '_';

    private static final String NULLSTR = "";

    private static final int MAX_INDEX = 10;

    public static boolean hasLength(@Nullable String str) {
        return str != null && !str.isEmpty();
    }

    /**
     * 将字符串中特定模式的字符转换成map中对应的值
     * <p>
     * use: format("my name is ${name}, and i like ${like}!", {"name":"L.cm", "like": "Java"})
     *
     * @param message 需要转换的字符串
     * @param params  转换所需的键值对集合
     * @return 转换后的字符串
     */
    public static String format(@Nullable String message, @Nullable Map<String, Object> params) {
        // message 为 null 返回空字符串
        if (message == null) {
            return "";
        }
        // 参数为 null 或者为空
        if (params == null || params.isEmpty()) {
            return message;
        }
        // 替换变量
        StringBuilder sb = new StringBuilder((int) (message.length() * 1.5));
        int cursor = 0;
        for (int start, end; (start = message.indexOf("${", cursor)) != -1 && (end = message.indexOf("}", start)) != -1; ) {
            sb.append(message, cursor, start);
            String key = message.substring(start + 2, end);
            Object value = params.get(StringUtil.trimWhitespace(key));
            sb.append(value == null ? "" : value);
            cursor = end + 1;
        }
        sb.append(message.substring(cursor));
        return sb.toString();
    }

    public static String format(@Nullable String message, @Nullable Object... arguments) {
        if (message == null) {
            return "";
        } else if (arguments != null && arguments.length != 0) {
            StringBuilder sb = new StringBuilder((int) ((double) message.length() * 1.5D));
            int cursor = 0;
            int index = 0;

            int start;
            int end;
            for (int argsLength = arguments.length; (start = message.indexOf(123, cursor)) != -1 && (end = message.indexOf(125, start)) != -1 && index < argsLength; ++index) {
                sb.append(message, cursor, start);
                sb.append(arguments[index]);
                cursor = end + 1;
            }

            sb.append(message.substring(cursor));
            return sb.toString();
        } else {
            return message;
        }
    }

    public static String trimWhitespace(String str) {
        if (!hasLength(str)) {
            return str;
        } else {
            int beginIndex = 0;

            int endIndex;
            for (endIndex = str.length() - 1; beginIndex <= endIndex && Character.isWhitespace(str.charAt(beginIndex)); ++beginIndex) {
            }

            while (endIndex > beginIndex && Character.isWhitespace(str.charAt(endIndex))) {
                --endIndex;
            }

            return str.substring(beginIndex, endIndex + 1);
        }
    }

    /**
     * 驼峰式命名法 例如：user_name->userName
     */
    public static String toCamelCase(String s) {
        if (s == null) {
            return null;
        }
        s = s.toLowerCase();
        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (c == SEPARATOR) {
                upperCase = true;
            } else if (upperCase) {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 自动生成UUID
     *
     * @return
     */
    public static String getUUID() {
        String uuid = "";
        for (int i = 0; i < MAX_INDEX; i++) {
            uuid = UUID.randomUUID().toString().replaceAll("-", "");
        }
        return uuid;
    }

    /**
     * 秒转换格式 HH:mm:ss
     *
     * @return
     */
    public static String addDuration(long num) {
        long temp = 0;
        StringBuffer sb = new StringBuffer();
        temp = num / 3600;
        sb.append((temp < 10) ? "0" + temp + ":" : "" + temp + ":");
        temp = num % 3600 / 60;
        sb.append((temp < 10) ? "0" + temp + ":" : "" + temp + ":");

        temp = num % 3600 % 60;
        sb.append((temp < 10) ? "0" + temp : "" + temp);
        return sb.toString();
    }

    /**
     * 根据身份证验证男女
     *
     * @param idCard 身份证
     * @return
     */
    public static String checkSex(String idCard) {
        String sex = idCard.substring(16, 17);
        if (Integer.parseInt(sex) % 2 == 0) {
            sex = "female";
        } else {
            sex = "male";

        }
        return sex;
    }

    /**
     * 功能：判断字符串是否为数字
     *
     * @param str
     * @return
     */
    private static boolean isNumeric(String str) {
        String regex = "[0-9]*";
        Pattern pattern = Pattern.compile(regex);
        Matcher isNum = pattern.matcher(str);
        if (isNum.matches()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 功能：判断字符串是否为日期格式
     *
     * @param strDate
     * @return
     */
    public static boolean isDate(String strDate) {
        String regex = "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))?$";
        Pattern pattern = Pattern.compile(regex);
        Matcher m = pattern.matcher(strDate);
        if (m.matches()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 去空格
     */
    public static String trim(String str) {
        return (str == null ? "" : str.trim());
    }

    /**
     * 是否包含字符串
     *
     * @param str  验证字符串
     * @param strs 字符串组
     * @return 包含返回true
     */
    public static boolean inStringIgnoreCase(String str, String... strs) {
        if (str != null && strs != null) {
            for (String s : strs) {
                if (str.equalsIgnoreCase(trim(s))) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空，则返回空字符串。 例如：HELLO_WORLD->HelloWorld
     *
     * @param name 转换前的下划线大写方式命名的字符串
     * @return 转换后的驼峰式命名的字符串
     */
    public static String convertToCamelCase(String name) {
        StringBuilder result = new StringBuilder();
        // 快速检查
        if (name == null || name.isEmpty()) {
            // 没必要转换
            return "";
        } else if (!name.contains("_")) {
            // 不含下划线，仅将首字母大写
            return name.substring(0, 1).toUpperCase() + name.substring(1);
        }
        // 用下划线将原始字符串分割
        String[] camels = name.split("_");
        for (String camel : camels) {
            // 跳过原始字符串中开头、结尾的下换线或双重下划线
            if (camel.isEmpty()) {
                continue;
            }
            // 首字母大写
            result.append(camel.substring(0, 1).toUpperCase());
            result.append(camel.substring(1).toLowerCase());
        }
        return result.toString();
    }

    @SuppressWarnings("unchecked")
    public static <T> T cast(Object obj) {
        return (T) obj;
    }

    /**
     * * 判断一个字符串是否为空串
     *
     * @param str String
     * @return true：为空 false：非空
     */
    public static boolean isEmpty(String str) {
        return isNull(str) || NULLSTR.equals(str.trim());
    }

    /**
     * * 判断一个对象是否为空
     *
     * @param object Object
     * @return true：为空 false：非空
     */
    public static boolean isNull(Object object) {
        return object == null;
    }

    /**
     * * 判断一个对象是否非空
     *
     * @param object Object
     * @return true：非空 false：空
     */
    public static boolean isNotNull(Object object) {
        return !isNull(object);
    }

    /**
     * * 判断一个对象数组是否非空
     *
     * @param objects 要判断的对象数组
     * @return true：非空 false：空
     */
    public static boolean isNotEmpty(Object[] objects) {
        return !isEmpty(objects);
    }

    /**
     * * 判断一个对象数组是否为空
     *
     * @param objects 要判断的对象数组
     *                * @return true：为空 false：非空
     */
    public static boolean isEmpty(Object[] objects) {
        return isNull(objects) || (objects.length == 0);
    }


    /**
     * 汉字转为全拼字母
     *
     * @param str
     * @return
     */
    public static String hanYuToPinyin(String str) {
        try {
            if (!StringUtil.isEmpty(str)) {
                HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
                //拼音小写
                format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
                //不带声调
                format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
                String pinyin = PinyinHelper.toHanYuPinyinString(str, format, "", true);
                return pinyin;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 截取末尾获取字符串
     *
     * @param str
     * @param n
     * @return
     */
    public static String interceptString(String str, int n) {
        return str.substring(str.length() - n);
    }

    /**
     * 密码校验
     * @param password
     * @return
     */
    /**
     * 检查密码是否符合规则,
     * 1.密码长度至少8位以上<br/>
     * 2.密码应至少包含大写字母，小写字母，数字，特殊符号中的三项<br/>
     * 3.禁止使用相同的数字或字符作为密码，如111111，aaaaaa等<br/>
     * 4.禁止使用连续升序或降序的数字或字母作为密码，如123456，abcdef等<br/>
     * true检验合格
     * false检验不合格
     */
    public static boolean checkPwd(String password) {
        //数字
        String REG_NUMBER = ".*\\d+.*";
        //小写字母
        String REG_UPPERCASE = ".*[A-Z]+.*";
        //大写字母
        String REG_LOWERCASE = ".*[a-z]+.*";
        //特殊符号
        String REG_SYMBOL = ".*[~!@#$%^&*()_+|<>,.?/:;'\\[\\]{}\"]+.*";
        //密码为空或者长度小于8位则返回false
        if (password == null || password.length() < 8) return false;
        int j = 0;
        if (password.matches(REG_NUMBER)) j++;
        if (password.matches(REG_LOWERCASE)) j++;
        if (password.matches(REG_UPPERCASE)) j++;
        if (password.matches(REG_SYMBOL)) j++;
        if (j < 3) return false;

        char[] chars = password.toCharArray();
//		int flag1 = 0;
//		int flag2 = 0;
        for (int i = 0; i < chars.length - 5; i++) {
            int n1 = chars[i];
            int n2 = chars[i + 1];
            int n3 = chars[i + 2];
            int n4 = chars[i + 3];
            int n5 = chars[i + 4];
            int n6 = chars[i + 5];
            // 判断重复字符
            if (n1 == n2 && n1 == n3 && n1 == n4 && n1 == n5 && n1 == n6) {
                return false;
            }
            // 判断连续字符： 正序 + 倒序
            if ((n1 + 1 == n2 && n1 + 2 == n3 && n1 + 3 == n4 && n1 + 4 == n5 && n1 + 5 == n6) || (n1 - 1 == n2 && n1 - 2 == n3 && n1 - 3 == n4 && n1 - 4 == n5 && n1 - 5 == n6)) {
                return false;
            }
        }

//		if(flag1>=6){
//			return false;
//		}
//		if(flag2>=6){
//			return false;
//		}
        return true;
    }

    /**
     * 字符串结尾若是c则去除
     *
     * @param str
     * @param c
     * @return
     */
    public static String strTrim(String str,String c) {
        //lastIndexOf获取最后一个逗号的索引，判断是否是字符串的最后一位
        if(str.lastIndexOf(c) == str.length()-1) {
            return str.substring(0, str.length()-1);
        }else{
            return str;
        }
    }


}
